﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PSLib.Parsing.Common;
using Antlr.Runtime;

namespace PSLib.Parsing.Common
{
    public class ElementSpan
    {
        public ElementSpan()
        {

        }

        public bool Contains(ElementPosition position)
        {
            return (this.IsEmpty) ? false : position >= this.Start && position < this.End;
        }

        public bool Intersects(ElementSpan span)
        {
            if (span.IsEmpty) return false;

            int startComp = this.Compare(span.Start);
            int endComp = this.Compare(span.End);
            
            if (startComp == 0 || endComp == 0) return true;
            if (startComp > 0 && endComp < 0) return true;
            if (startComp < 0 && endComp > 0) return true;

            return false;
        }

        public int Compare(ElementSpan span)
        {
            if (span.IsEmpty) return -1;

            if (this.Intersects(span)) return 0;
            else if (span.Start >= this.End) return 1;
            else if (span.End <= this.Start) return -1;
            else throw new Exception("Unexpected");
        }

        public int Compare(ElementPosition position)
        {
            if (this.Contains(position)) return 0;
            else if (position >= this.End ) return -1;
            else if (position < this.Start) return 1;
            else throw new Exception("Unexpected");
        }


        public override string ToString()
        {
            string result = string.Empty;
            if (this.IsEmpty) result = "(Empty)";
            else result = string.Format("({0}|{1})", this.Start, this.End);
            return result;
        }

        public bool IsEmpty
        {
            get
            {
                if (this.Start == null || this.End == null) return true;
                else return this.Start >= this.End;
            }
        }
        public ElementPosition Start { get; set; }
        public ElementPosition End { get; set; }
    }

    public static class ElementSpanExtension
    {
        public static ElementSpan GetSpan(this IToken token, CommonTokenStream stream)
        {
            ElementSpan span = new ElementSpan();
            span.Start = token.GetPosition();
            span.End = ElementPosition.GlobalEnd;
            if (token.TokenIndex + 1 < stream.Count)
            {
                span.End = stream.Get(token.TokenIndex + 1).GetPosition();
            }
            return span;
        }
    }
}
